<?php
namespace app\admin\helper;

class Verify {
    private static $errors = [];
    private static $self = null;
    private $conf = [];
    private $fields = [];
    public static function validateData($validate_field,$data){
        // $validate_field = [
        //     'family'=>'required',
        //     'parent_id'=>'required',
        //     'group_id'=>'required',
        //     'user_id'=>'required',
        //     'project_group_id'=>'required',
        //     'name'=>'required',
        //     'login_name'=>'required',
        //     'pass'=>'required',
        // ];
        self::$errors = [];
        if(self::$self==null){
            self::$self = new self();
        }
        foreach ($validate_field as $field=>$item){
            if(isset($data[$field])){
                $bool = call_user_func([self::$self,$item],['field'=>$field,'data'=>$data[$field]]);
                if(!$bool){
                    return $bool;
                }
            }else{
                self::$errors[]= $field.'不能为空';
                return false;
            }
        }
        return true;
    }
    /**
     * [run 执行验证过程]
     * @return [type] [description]
     */
    public function run($data)
    {
        $this->validConf($this->conf,$data);
    }
    public function validConf($validate_field,$data){
        self::$errors = [];
        var_dump($validate_field);
        foreach ($validate_field as $v){
            //$field=>$item
            //list($field,$item) = $
            $field = array_key_first($v);
            $item = $v[$field];
            $item[1][] = $data[$field];
            var_dump($item);
            if(isset($data[$field])){
                $bool = call_user_func([$this,$item[0]],...$item[1]);
                if(!$bool){
                    return $bool;
                }
            }else{
                self::$errors[]= $field.'不能为空';
                return false;
            }
        }
        return true;
    }
    public function required($field){
        //$this->conf[] = ["$field"]
    }
    protected static function _length($field, $length, $value)
    {
        if ($length!==strlen($value)){
            self::$errors[]=$field.'长度限制为'.$length;
            return false;
        }
        return true;
    }
    protected static function _required($data){
        if (null===$data['data']){
            self::$errors[]=$data['field'].'值为空';
            return false;
        }
        return true;
    }
    protected static function _phone($data){
        $data['data'] = trim($data['data']);
        if (!preg_match('/^1[345678]{1}\d{9}$/',$data['data'])){
            self::$errors[]=$data['field'].'手机号格式错误';
            return false;
        }
        return true;
    }

    protected static function _email($data){
        $data['data'] = trim($data['data']);
        if (!preg_match('/^[_a-z0-9-]+(\.[_a-z0-9-]+)*@[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,})$/',$data['data'])){
            self::$errors[]=$data['field'].'邮箱格式错误';
            return false;
        }
        return true;
    }

    public static function getError(){
        return self::$errors;
    }
    function __call($name,$arguments)
    {
        echo $name.'_';
        $class = new \ReflectionClass(self::CLASS);
        $methods = $class->getMethods();
        //var_dump($methods);
        foreach($methods as $method){
            if($method->name=='_'.$name)
            {
                $ref = $class->getMethod('_'.$name);
                $params = $ref->getParameters();
                //var_dump($params);
                //echo $ref->getNumberOfParameters();
                var_dump($arguments);
                //检查传入参数和实际执行函数参数个数一致，实际执行函数比配置参数多1个字段名参数
                //后面实际执行时参数数组中第一个位置为验证数据字段名末尾追加一个参数位设为验证数据字段值
                if(count($arguments)==$ref->getNumberOfParameters()-1)
                {
                    $this->fields[] = $arguments[0];
                    $this->conf[] = [
                        "{$arguments[0]}"=>[
                            "_$name",$arguments
                        ]
                    ];
                    //var_dump($this->conf);
                }else{
                    echo '_参数个数不一致_';
                }
                //$this->conf[] = ['_'.$name,$arguments];
            }
        }
        //echo $methods[0]->name;
    }
}


/**
 * 基本思路:
 * 通过__call查询是否存在下划线开头的验证方法
 * 再加入配置数组将需要验证的字段和其他参数存起来
 * 最后再通run方法对传入数据执行验证
 * 验证过程循环获取数据和开始设置的检查规则
 */
$verify = new verify();

$verify->length('name',6);//验证字段名为'name',长度为5
//$cdata = ['name'=>'1234567'];
$verify->run(['name'=>'123456']);
var_dump($verify->getError());